<?php
/**
 * 页面缓存类
 *
 * 通过简单的添加一语句实现当前页面缓存，提供系统性能
 * 配置项:
 * page_cache.path 页面缓存存放目录
 *
 * @author    Garbin
 * @package    Library
 * @subpackage Cache
 */

/**
 * app启动前检查当前请求缓存是否命中
 */
SparrowHook::apply('before_app_run', array('PageCache', 'check'));

/**
 * 依赖cache类
 */
Lib::import('sparrow.cache');

/**
 * 页面缓存主体类
 *
 * 负责缓存检查及生成
 * @static
 */
class PageCache extends Object
{
    /**
     * 检查缓存
     *
     * 如果缓存命中，则直接读取缓存。
     *
     * @author    Garbin
     * @access public
     * @static
     * @return bool
     */
    static public function check()
    {
        $cache = self::getCacheServer();
        $cached_file = $cache->get(self::getKey());
        if ($cached_file !== false)
        {
            echo $cached_file;

            // 缓存命中，无需再往下执行
            return false;
        }
        else
        {
            ob_start();

            // 缓存未命中，打开输出控制并往下执行
            return true;
        }
    }

    /**
     * 开启当前页面缓存
     *
     * 为当前页面开启缓存，可指定缓存更新周期
     *
     * @author    Garbin
     * @access public
     * @static
     * @param  int $ttl 缓存更新周期，单位为秒，默认是3600秒
     * @return void
     */
    static public function cache($ttl = 3600)
    {
        register_shutdown_function(array('PageCache', 'doCache'), $ttl);
    }

    /**
     * 生成缓存，系统回调函数
     *
     * 将本页面输出内容生成缓存，供下次读取
     *
     * @author    Garbin
     * @access public
     * @static
     * @param  int $ttl 缓存更新周期
     * @return void
     */
    static public function doCache($ttl)
    {
        $cache = self::getCacheServer();
        $cache->set(self::getKey(), ob_get_contents(), $ttl);
    }

    /**
     * 获取缓存服务器
     *
     * 获取缓存服务器实例，使用FilecacheServer将输出内容缓存至硬盘
     *
     * @author    Garbin
     * @access public
     * @static
     * @return Object
     */
    static public function getCacheServer()
    {
        $cache = null;
        if ($cache === null)
        {
            $cache = new FilecacheServer();
            $cache->setPath(app_config('page_cache.path'));
        }

        return $cache;
    }

    /**
     * 获取页面唯一ID
     *
     * 获取页面唯一ID，在缓存内容时需要用到
     *
     * @author    Garbin
     * @access public
     * @static
     * @return string 缓存ID
     */
    static public function getKey()
    {
        $tmp = $_GET;
        ksort($tmp);

        return md5(implode('&', $tmp));
    }

}
